<template>
  <a-modal
    :title="formConfig.title"
    v-model:visible="state.visible"
    :width="formConfig.width || 900"
    centered
    :destroyOnClose="true"
    :maskClosable="false"
  >
    <a-form ref="formRef" name="submitForm" :model="state.formObj">
      <a-row :gutter="16">
        <template :key="item.name" v-for="item in formConfig.items">
          <a-col v-if="item.dynamic" :span="24">
            <!-- 动态属性 -->
            <a-form-item :label="item.label">
              <div :style="{ maxHeight: '400px', overflowY: 'auto' }">
                <div
                  v-for="(groupObj, i) in state.formObj[item.name] || []"
                  :style="{
                    display: 'flex',
                    alignItems: 'center',
                    border: '1px solid #dedede',
                    padding: '4px',
                  }"
                  :key="i"
                >
                  <div style="flex: 1">
                    <a-row :gutter="5">
                      <a-col
                        v-for="(field, j) in item.group"
                        :key="j"
                        :span="field.type === 'hidden' ? 0 : field.span || 24"
                      >
                        <FormItem
                          :item="{
                            ...field,
                            name: [item.name, i, field.name],
                            style: { marginBottom: 0 },
                          }"
                          v-model:obj="groupObj[field.name]"
                        />
                      </a-col>
                    </a-row>
                  </div>
                  <div :style="{ marginLeft: '5px' }">
                    <a-button
                      type="dashed"
                      size="small"
                      @click="removeRow(item.name, i)"
                    >
                      <template #icon><DeleteOutlined /></template
                    ></a-button>
                  </div>
                </div>
              </div>
              <a-form-item>
                <a-button type="dashed" block @click="addRow(item.name)">
                  <template #icon><PlusOutlined /></template>添加{{
                    item.label
                  }}</a-button
                >
              </a-form-item>
            </a-form-item>
          </a-col>
          <a-col
            v-else
            :span="
              item.type === 'hidden' ? 0 : _.isNil(item.span) ? 24 : item.span
            "
          >
            <FormItem :item="item" v-model:obj="state.formObj[item.name]" />
          </a-col>
        </template>
      </a-row>
    </a-form>
    <template #footer>
      <span class="dialog-footer">
        <a-button @click="cancel">取消</a-button>
        <a-button type="primary" @click="submit(formRef)">提交</a-button>
      </span>
    </template>
  </a-modal>
</template>
<script setup>
import _ from "lodash";
import { reactive, ref } from "vue";
import FormItem from "./FormItem.vue";

const formRef = ref(null);
const props = defineProps({
  formConfig: {
    required: true,
    type: Object,
  },
});
const emit = defineEmits(["submit"]);

const state = reactive({ formObj: {}, visible: false });

const handleOpenForm = (obj) => {
  state.visible = true;
  // 获取所有监听的项
  _.each(props.formConfig.items, (item) => {
    if (item.onChange) {
      item.onChange(obj[item.name]);
    }
  });
  state.formObj = obj;
};

const submit = (formEl) => {
  formEl
    .validate()
    .then((value) => {
      emit("submit", value);
    })
    .catch((info) => {
      console.log("Validate Failed:", info);
    });
};

const cancel = () => {
  formRef.value.resetFields();
  state.formObj = null;
  state.visible = false;
};

const addRow = (name) => {
  // 获取某字段的子属性
  const item = _.find(props.formConfig.items, { name });
  if (item.group) {
    // 子属性转为空对象集合
    const obj = _.reduce(
      item.group,
      (_obj, o) => {
        _obj[o.name] = null;
        return _obj;
      },
      {}
    );
    // 空对象追加到子属性集合中
    if (state.formObj[name] instanceof Array) {
      state.formObj[name].push(obj);
    } else {
      state.formObj[name] = [obj];
    }
  }
};

const removeRow = (name, index) => {
  const array = state.formObj[name] || [];
  array.splice(index, 1);
  state.formObj[name] = _.cloneDeep(array);
};

defineExpose({ handleOpenForm, cancel, submit });
</script>
<style lang="less" scoped>
:deep(.ant-form-item-label) {
  width: 150px;
}

:deep(.ant-input-number) {
  width: 100%;
}
</style>
